package com.googlecode.stil.playground;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.handler.IUpdateHandler;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.primitive.Rectangle;
import org.andengine.entity.scene.IOnSceneTouchListener;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.extension.physics.box2d.FixedStepPhysicsWorld;
import org.andengine.extension.physics.box2d.PhysicsConnector;
import org.andengine.extension.physics.box2d.PhysicsFactory;
import org.andengine.extension.physics.box2d.PhysicsWorld;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
import org.andengine.ui.activity.BaseGameActivity;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.MassData;

public class BodyTest extends BaseGameActivity {

	private static final int CAMERA_WIDTH = 720;
	private static final int CAMERA_HEIGHT = 480;

	private FixtureDef ballDef = PhysicsFactory.createFixtureDef(0f, 0f, 0f);
	private FixtureDef wallDef = PhysicsFactory.createFixtureDef(0f, 0f, 0f);

	private Camera camera;

	private Body[] ballBodies;
	private boolean applyForce;
	private int direction = -1;

	@Override
	public EngineOptions onCreateEngineOptions() {
		camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
	}

	@Override
	public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) {
		pOnCreateResourcesCallback.onCreateResourcesFinished();
	}

	@Override
	public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) {

		Scene scene = new Scene();
		scene.setBackground(new Background(0.5f, 0.3f, 0.5f));
		PhysicsWorld physics = new FixedStepPhysicsWorld(60, new Vector2(0, 0), false);

		buildWalls(scene, physics);
		scene.registerUpdateHandler(physics);

		ballBodies = new Body[3];
		int n = 3;
		final VertexBufferObjectManager vertexBufferObjectManager = this.getVertexBufferObjectManager();
		for (int k = 0; k < n; k++) {
			Rectangle ball = new Rectangle((((CAMERA_WIDTH - 50) / (n + 1)) * (k + 1)), ((CAMERA_HEIGHT - 50) / 2), 50, 50, vertexBufferObjectManager);

			ball.setColor(k * 0.1f, k * 0.5f, k * 0.9f);

			ballBodies[k] = PhysicsFactory.createBoxBody(physics, ball, BodyType.DynamicBody, ballDef);
			MassData mass = ballBodies[k].getMassData();
			mass.mass = 1;
			ballBodies[k].setMassData(mass);

			scene.attachChild(ball);

			physics.registerPhysicsConnector(new PhysicsConnector(ball, ballBodies[k], true, true));
		}

		scene.setOnSceneTouchListener(new IOnSceneTouchListener() {
			@Override
			public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
				if (pSceneTouchEvent.isActionDown()) {
					direction = direction * -1;
					System.out.println("direction is " + direction);

					// ballBodies[0].applyForce(new Vector2(0f, -50f), new
					// Vector2(ballBodies[0].getWorldCenter()));
					applyForce = true;

					ballBodies[1].applyLinearImpulse(new Vector2(0f, direction * 10f), new Vector2(ballBodies[1].getWorldCenter()));

					ballBodies[2].setLinearVelocity(new Vector2(0f, direction * 10f));

				} else if (pSceneTouchEvent.isActionUp()) {
					// applyForce = false;
				}
				return true;
			}
		});

		scene.registerUpdateHandler(new IUpdateHandler() {

			@Override
			public void reset() {
			}

			@Override
			public void onUpdate(float pSecondsElapsed) {
				if (applyForce) {
					ballBodies[0].applyForce(new Vector2(0f, direction * 10f), new Vector2(ballBodies[0].getWorldCenter()));
				}
			}
		});

		pOnCreateSceneCallback.onCreateSceneFinished(scene);
	}

	@Override
	public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) {
		pOnPopulateSceneCallback.onPopulateSceneFinished();
	}

	private void buildWalls(Scene scene, PhysicsWorld physics) {
		final VertexBufferObjectManager vertexBufferObjectManager = this.getVertexBufferObjectManager();
		Rectangle roof = new Rectangle(0, 0, CAMERA_WIDTH, 5, vertexBufferObjectManager);
		roof.setColor(1, 0, 0);
		PhysicsFactory.createBoxBody(physics, roof, BodyType.StaticBody, wallDef);
		scene.attachChild(roof);

		Rectangle floor = new Rectangle(0, CAMERA_HEIGHT - 5, CAMERA_WIDTH, 5, vertexBufferObjectManager);
		floor.setColor(1, 1, 0);
		PhysicsFactory.createBoxBody(physics, floor, BodyType.StaticBody, wallDef);
		scene.attachChild(floor);

		Rectangle left = new Rectangle(0, 0, 5, CAMERA_HEIGHT, vertexBufferObjectManager);
		left.setColor(0, 0, 1);
		PhysicsFactory.createBoxBody(physics, left, BodyType.StaticBody, wallDef);
		scene.attachChild(left);

		Rectangle right = new Rectangle(CAMERA_WIDTH - 5, 0, 5, CAMERA_HEIGHT, vertexBufferObjectManager);
		right.setColor(0, 1, 1);
		PhysicsFactory.createBoxBody(physics, right, BodyType.StaticBody, wallDef);
		scene.attachChild(right);
	}
}